import type { NavItem, UserMenuItem } from '../../../components/navbar/types'
import type { ComponentStyleIdType } from '../../../types/interfaces'
import { Navbar } from '../../../components/navbar'
import { BaseModule } from '../../../lib/abstract'
import { ElementManager } from '../../../lib/element_manager'
import { IconService } from '../../../lib/icons'
import { ICON_IDS } from '../../../lib/icons/types/constants'
import { PageHandler } from '../../../lib/page_handler'
import { GREASY_FORK_NAVBAR_CATEGORY_CONFIG } from '../../../lib/page_handler/platform/greasyfork/types'
import { ToolKit } from '../../../lib/utils/toolkit'
import { DonateManager } from '../../../menu/donate'
import {
  BUILD_CONFIG,
  ComponentStyleId,
  HOSTNAME,
  logger,
  MODULE_CONFIG,
  SignType,
  SUPPORTED_PLATFORMS,
} from '../../../types/constants'
import { SYMBOLS } from '../../../types/interfaces'
import { ConfigManager } from '../../config_manager'
import { StyleManager } from '../../style_manager'

interface Config {
  enabled?: boolean
  navbarCollapsed?: boolean
}

export class NavbarMenu extends BaseModule {
  readonly id: string = 'navbar_menu'
  readonly styleId: string = ComponentStyleId[this.name]
  isInitialized: boolean = false
  readonly supportedPlatforms: string[] = ConfigManager.getInstance().moduleSupportedPlatforms(this.name)
  private static instance: NavbarMenu
  readonly pageHandler: PageHandler = PageHandler.getInstance()
  readonly iconService: IconService = IconService.getInstance()
  private donateToast = DonateManager.getInstance()
  private navbar: Navbar | null = null

  config: Config = {
    enabled: true,
    navbarCollapsed: false,
  }

  get name(): ComponentStyleIdType {
    return 'NavbarMenu'
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): NavbarMenu {
    if (!NavbarMenu.instance) {
      NavbarMenu.instance = new NavbarMenu()
    }
    return NavbarMenu.instance
  }

  handleCleanupReferences(): void {
    this.navbar?.destroy()
    this.navbar = null
  }

  core(): void {
    this.loadConfig()

    if (!this.config.enabled)
      return

    this.createNavbar()

    // 注册样式
    StyleManager.getInstance().registerStyle(this.styleId, this.getStyles(), false, true)
  }

  onToggleCallback(_id: string, checked: boolean): void {
    super.onToggleCallback(_id, checked)
  }

  createNavbar(): void {
    switch (HOSTNAME) {
      case SUPPORTED_PLATFORMS.GREASY_FORK:
      // TODO：未实现通知红点以及个数展示
      {
        const sign_type = this.pageHandler.services.greasyFork.getSignType()
        const sign_meta = {
          id: sign_type,
          label: sign_type === SignType.SignIn
            ? `${SYMBOLS.NAV.LOGIN} 开始登录`
            : `${SYMBOLS.NAV.LOGOUT} 退出登录`,
          path: sign_type === SignType.SignIn
            ? this.pageHandler.services.greasyFork.getSignInLink()
            : this.pageHandler.services.greasyFork.getSignOutLink(),
        }

        const userAvatarLink = sign_type === SignType.SignIn
          ? this.pageHandler.services.greasyFork.getSignInLink()
          : this.pageHandler.services.greasyFork.getCurrentUserIndexLink()

        const isCreator = this.pageHandler.features.user.isCreator(this.pageHandler.services.greasyFork.getCurrentUserId())

        const userName = sign_type === SignType.SignIn
          ? '游客'
          : this.pageHandler.services.greasyFork.getCurrentUserName()

        this.navbar = new Navbar({
          id: MODULE_CONFIG.PLATFORM.greasyFork.navbarId,
          brandLogo: this.iconService.api.icon.asDataUrl(ICON_IDS.platform.greasyFork),
          brandName: 'Greasy Fork',
          items: [
            {
              id: 'index',
              label: '网站首页',
              path: '/',
              iconType: ICON_IDS.user.home,
              external: false,
            },
            {
              id: 'discussions',
              label: '社区论坛',
              path: '/discussions',
              iconType: ICON_IDS.other.discussions,
              external: false,
            },
            {
              id: 'user-list',
              label: '用户总览',
              path: '/users',
              iconType: ICON_IDS.role.author,
              external: false,
            },
            {
              id: 'script',
              label: '脚本中心',
              iconType: ICON_IDS.other.script,
              children: [
                {
                  id: 'script-list',
                  label: `${SYMBOLS.DOCUMENTS.CLIPBOARD} 脚本总览`,
                  path: '/scripts',
                  external: false,
                },
                {
                  id: 'script-site',
                  label: `${SYMBOLS.NETWORK.GLOBE} 热门站点`,
                  path: '/scripts/by-site',
                  external: false,
                },
                {
                  id: 'script-libraries',
                  label: `${SYMBOLS.DOCUMENTS.BOOKS} 仓库资源`,
                  path: '/scripts/libraries',
                  external: false,
                },
                {
                  id: 'search',
                  label: `${SYMBOLS.UI.SEARCH} 高级搜索`,
                  path: '/search',
                  external: false,
                },
              ],
            },
            {
              id: 'content',
              label: '内容管理',
              iconType: ICON_IDS.other.content,
              children: [
                {
                  id: 'script-site',
                  label: `${SYMBOLS.DOCUMENTS.MEMO} 管理日志`,
                  path: '/moderator_actions',
                  external: false,
                },
                {
                  id: 'dev-document',
                  label: `${SYMBOLS.DOCUMENTS.BOOK} 开发文档`,
                  path: 'https://www.tampermonkey.net/documentation.php',
                  external: true,
                },
              ],
            },
            {
              id: 'more',
              label: '更多功能',
              iconType: ICON_IDS.other.more,
              children: [
                {
                  id: 'help',
                  label: `${SYMBOLS.STATUS.QUESTION} 帮助中心`,
                  path: '/help',
                  external: false,
                },
                {
                  id: 'donate',
                  label: `${SYMBOLS.SHAPES.HEART} 支持我`,
                  external: false,
                },
              ],
            },
          ],
          userMenuItems: [
            {
              id: 'profile',
              label: `${SYMBOLS.USER.USER_CENTER} 个人资料`,
              path: this.pageHandler.services.greasyFork.getCurrentUserIndexLink(),
              external: true,
              enabled: sign_type !== SignType.SignIn,
            },
            {
              id: 'hide-navbar',
              label: `${SYMBOLS.UI.BLOCK} 隐藏导航`,
            },
            {
              id: sign_meta.id,
              label: sign_meta.label,
              path: sign_meta.path,
              external: false,
            },
          ],
          brandLink: `https://greasyfork.org/${navigator.language}`,
          userName: `${ToolKit.ui.icon.getSeasonIcon()} ${userName}`,
          userAvatar: sign_type === SignType.SignIn
            ? this.iconService.api.icon.asDataUrl(ICON_IDS.role.visitor)
            : isCreator
              ? BUILD_CONFIG.IMAGE.CREATOR_AVATAR_URL
              : this.iconService.api.icon.asDataUrl(ICON_IDS.user.avatarBlue),
          userAvatarLink,
          activeId: 'index',
          initiallyCollapsed: this.config.navbarCollapsed,
          onCollapseChange: (collapsed: boolean) => {
            this.updateConfig({ navbarCollapsed: collapsed })
          },
          onItemClick: async (item: NavItem) => {
            if (item.id === 'donate') {
              await this.donateToast.showDialog()
            }
          },
          onUserMenuItemClick: (item: UserMenuItem) => {
            const path = item.path || '#'
            if (item.id === 'hide-navbar') {
              this.navbar?.setCollapsed(true)
            }

            // 执行跳转
            item.external ? ToolKit.browser.url.openNewTab(path) : ToolKit.browser.url.openTab(path)
          },
        })
      }
    }

    if (!this.navbar)
      return

    const $body = $('body')

    // 插入到 DOM 并挂载
    const $navbar = $(this.navbar.render())
    $body.prepend($navbar)
    this.navbar.mount($body)

    // 更新导航激活项
    this.activeNavbarItem()

    // 记录创建
    this.tracker.creation($navbar)

    // 标记为项目元素
    ToolKit.browser.platform.markProjectElement($navbar)
  }

  activeNavbarItem(): void {
    if (!this.navbar)
      return

    if (HOSTNAME === SUPPORTED_PLATFORMS.GREASY_FORK) {
      const pageType = this.pageHandler.services.greasyFork.pageType
      this.navbar.setActiveItem(GREASY_FORK_NAVBAR_CATEGORY_CONFIG[pageType]?.menuId || '')
    }
  }

  applyConfig(config: Partial<Config>): void {
    super.updateConfig(config)

    this.createNavbar()

    logger.info(`[${this.name}] Config updated and apply`, this.config)
  }

  getStyles(): string {
    return `
${this.greasyForkStyles()}
`
  }

  greasyForkStyles(): string {
    return HOSTNAME === SUPPORTED_PLATFORMS.GREASY_FORK
      ? `
/* 导航栏存在时，设置间距 */
${ElementManager.getInstance().selector.navbar} { 
  > .width-constraint {
    margin-top: ${MODULE_CONFIG.COMPONENTS.navbar.height} !important;
  }
}
`
      : ''
  }
}
